package com.heima.search.service.serviceImpl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.heima.article.api.ArticleContentFeign;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.common.dtos.PageResponseResult;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.search.dto.SearchDto;
import com.heima.search.doc.ArticleInfoDocument;
import com.heima.search.mapper.ArticleEsMapper;
import com.heima.search.service.ArticlerEsService;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.search.suggest.Suggest;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author mgw
 * @create 2021/10/7 18:20
 */
public class ArticlerEsServiceImpl implements ArticlerEsService {
    @Autowired
    private ArticleContentFeign articleContentFeign;
    @Autowired
    private ArticleEsMapper articleEsMapper;
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Autowired
    private RestHighLevelClient client;

    @Override
    public void allImport() {
        int page=1;
        while (true){
        ResponseResult list = articleContentFeign.list(1, page, 3);
        Page<ApArticle> pageInfo = JSON.parseObject(JSON.toJSONString(list.getData()), Page.class);
            List<ArticleInfoDocument>  articleInfoDocument = JSON.parseArray(JSON.toJSONString(pageInfo.getResult()), ArticleInfoDocument.class);
            articleEsMapper.saveAll(articleInfoDocument);
            if (page>pageInfo.getPages()){
                return;
            }
        }


    }


    @SneakyThrows
    @Override
    public PageResponseResult search(SearchDto searchDto) {
        SearchRequest request = new SearchRequest("atricle");
        request.source().query(StringUtils.isEmpty(searchDto.getKeywords())?
                QueryBuilders.matchAllQuery():QueryBuilders.matchQuery("title",searchDto.getKeywords()))
                .from((searchDto.getPage()-1)*searchDto.getSize()).size(searchDto.getSize()).sort("createdTime", SortOrder.DESC)
                .highlighter(new HighlightBuilder().field("title").requireFieldMatch(false));
        SearchResponse search = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        List<ArticleInfoDocument> documents=new ArrayList<>();
        for (SearchHit hit : search.getHits()) {
            //非高亮
            ArticleInfoDocument articleInfoDocument = JSON.parseObject(hit.getSourceAsString(), ArticleInfoDocument.class);
            //高亮
            HighlightField title = hit.getHighlightFields().get("title");
            if (title!=null){
                String txt = StringUtils.join(title.getFragments(), "...");
                articleInfoDocument.setTitle(txt);
            }
            documents.add(articleInfoDocument);
        }
        //封装分页对象
        long total = search.getHits().getTotalHits().value;
        PageResponseResult pageResponseResult = new PageResponseResult(searchDto.getPage(), searchDto.getSize(), (int) total);
       pageResponseResult.setData(documents);
       return pageResponseResult;
    }

    @Override
    public void saveToEs(ApArticle article) {
        ArticleInfoDocument articleInfoDocument = JSON.parseObject(JSON.toJSONString(article), ArticleInfoDocument.class);
        articleEsMapper.save(articleInfoDocument);
    }

    @Override
    public ResponseResult getSuggestions(String keyWord) {
        try {
            // 1.准备Request
            SearchRequest request = new SearchRequest("atricle");
            // 2.准备DSL
            request.source().suggest(new SuggestBuilder().addSuggestion(
                    "suggestions",
                    SuggestBuilders.completionSuggestion("suggestion")
                            .prefix(keyWord)
                            .skipDuplicates(true)
                            .size(10)
            ));
            // 3.发起请求
            SearchResponse response = client.search(request,RequestOptions.DEFAULT);
            // 4.解析结果
            Suggest suggest = response.getSuggest();
            // 4.1.根据补全查询名称，获取补全结果
            CompletionSuggestion suggestions = suggest.getSuggestion("suggestions");
            // 4.2.获取options
            List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
            // 4.3.遍历
            List<String> list = new ArrayList<>(options.size());
            for (CompletionSuggestion.Entry.Option option : options) {
                String text = option.getText().toString();
                list.add(text);
            }
            return ResponseResult.okResult(list);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}
